home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 6
/
FM Towns Free Software Collection 6.iso
/
t_os
/
book
/
src
/
cons.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-08
|
17KB
|
750 lines
/*
* console low I/O
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <ctype.h>
#include <egb.h>
#include <msdos.cf>
#include <mos.h>
#include <fmc.h>
#include "book.h"
#include "oaklib.h"
#include "cons.h"
#include "keyio.h"
#include "lib.h"
#include "mouse.h"
#define MODE_X 560
#define MODE_Y 452
#define FSIZE 16 /* フォント・サイズ */
#define PIX_BYTE 1 /* 画面モ-ドにより変化 16色=1 256色=1 32K色=2 */
#define FNT_X 8
#define FNT_Y 16
#define LINE_MAX 128
#define OPEN wp->opened
#define TOP_X wp->top_x
#define TOP_Y wp->top_y
#define BTM_X wp->btm_x
#define BTM_Y wp->btm_y
#define SIZ_X wp->siz_x
#define CUR_X (*wp->cur_x)
#define _CUR_X wp->cur_x
#define CUR_POS wp->cur_pos
#define CUT_X wp->cut_x
#define CUT_POS wp->cut_pos
#define KAN_COD wp->kan_cod
#define EDITBUF wp->editbuf
#define DSP_X wp->dsp_x
#define DSP_Y wp->dsp_y
#define DSP_LEN wp->dsp_len
typedef struct _WP
{
short opened ;
short top_x, top_y ;
short btm_x, btm_y ;
short siz_x ;
int *cur_x ;
short cur_pos ;
short cut_x, cut_pos ;
short kan_cod ;
char *editbuf ;
short dsp_x, dsp_y ;
short dsp_len ;
} WIND_t ;
static WIND_t act_wind = { FALSE,
0,0, 0,0, 0, NULL, 0,-1,-1, 0, NULL, 0,0,0 } ;
static WIND_t *wp = &act_wind ;
static char kan_mode[16];
static char cutbuf[LINE_MAX];
static char ktype[LINE_MAX];
static char linebuf[LINE_MAX];
static int linelen = 0;
void typecheck( char *type, char *buf, int width )
{
while( width-- > 0 )
{
if( iskanji( *buf ) && iskanji2( *(buf+1) ) )
{
*type++ = IS_KANJI1 ;
*type = IS_KANJI2 ;
buf++ ;
width-- ;
}
else
*type = IS_ANK ;
buf++, type++ ;
}
*type = IS_ANK ;
}
typedef enum { CUR_DISP, CUR_OFF } cursor ;
static void cur_dsp( cursor sw )
{
static int pos, cpos ;
auto int TOPx = TOP_X, y ;
if( sw == CUR_DISP )
{
TOPx -= ( TOPx % 2 ) ;
pos = CUR_X * FNT_X + TOPx ;
if( CUT_X >= 0 )
cpos = CUT_X * FNT_X + TOPx ;
}
y = ( CUT_POS >= 0 ) ? (DSP_Y+7):(DSP_Y+14) ;
box( pos,y, pos+FNT_X-1,y+1, 2,-1,MODE_XOR ) ;
if( CUT_POS >= 0 && CUT_POS < CUR_POS )
{
EGB_writeMode( gwork, MODE_XOR ) ;
pbox( cpos,DSP_Y, pos-1,DSP_Y+15, 2,2 ) ;
EGB_writeMode( gwork, MODE_PSET ) ;
}
}
static void cflush( void )
{
int i ;
char *p, buf[3] = "^ " ;
cur_dsp( CUR_OFF ) ;
if( DSP_LEN > 0 )
{
DSP_X = CUR_POS * FNT_X + TOP_X ;
wrt( (char *)&linebuf[CUR_POS], DSP_X,DSP_Y, CHR_COL,BAK_COL,FSIZE ) ;
DSP_LEN = 0 ;
for( i=0, p=(char *)&linebuf[CUR_POS] ; *p ; p++, i++ )
if( *p == CTRL_PRE )
{
buf[1] = *(p+1) ;
wrt( buf, DSP_X+i*8,DSP_Y, CTRL_COL,BAK_COL,FSIZE ) ;
}
}
CUR_POS = CUR_X ;
CUT_POS = CUT_X ;
cur_dsp( CUR_DISP ) ;
}
static void cut_paste( int sw )
{
int color ;
if( sw == TRUE ) /* 開始 */
{
pbox( 272,MODE_Y-2, 272+96,MODE_Y+16+1, CHR_COL,CHR_COL ) ;
wrt( "範囲指定中", 280,MODE_Y, BAK_COL,CHR_COL, 16 ) ;
CUT_X = CUR_X ;
}
else /* 終了 */
{
color = ( writepage == 0 ) ? 15 : 0 ;
pbox( 272,MODE_Y-2, 272+96,MODE_Y+16+1, color,color ) ;
CUT_X = -1 ;
}
}
void wind_close( void )
{
if( OPEN )
{
OPEN = FALSE ;
MOS_disp( MOS_OFF ) ;
cflush() ;
if( CUT_X != -1 )
cut_paste( FALSE ) ;
cur_dsp( CUR_OFF ) ;
MOS_disp( MOS_ON ) ;
strcpy( EDITBUF, linebuf ) ;
}
}
int wind_open( int x,int y, int len,int *curpos, char *init )
{
wind_close() ;
MOS_disp( MOS_OFF ) ;
OPEN = TRUE ;
TOP_X = x ;
TOP_Y = y ;
BTM_X = x + len*8 ;
BTM_Y = y + 15 ;
SIZ_X = len + 1 ;
_CUR_X = curpos ;
CUT_X = CUT_POS = -1 ;
CUR_POS = 0 ;
KAN_COD = 0 ;
DSP_X = TOP_X ;
DSP_Y = TOP_Y ;
DSP_LEN = 0 ;
EDITBUF = init ;
if( init == NULL )
{
linebuf[0] = '\0' ;
linelen = 0 ;
CUR_X = 0 ;
}
else
{
strcpy( linebuf, init ) ;
linelen = strlen( init ) ;
typecheck( ktype, linebuf, linelen ) ;
DSP_LEN = 1 ;
if( CUR_X > linelen )
CUR_X = linelen ;
if( ktype[CUR_X] == IS_KANJI2 )
CUR_X -- ;
}
cur_dsp( CUR_DISP ) ;
cflush() ;
MOS_disp( MOS_ON ) ;
return 0 ;
}
static int ins_char( char str[] )
{
REGS int i ;
if( linelen >= SIZ_X-1 )
return -1 ;
for( i = linelen ; i >= 0 ; i -- )
str[i+1] = str[i] ;
linelen ++ ;
return 0 ;
}
static int del_char( int pos )
{
REGS int i, len ;
len = ( ktype[pos]==IS_KANJI1 || linebuf[pos]==CTRL_PRE ) ? 2 : 1 ;
for( i = pos ; i < linelen ; i ++ )
linebuf[i] = linebuf[i+len] ;
if( linelen > 0 )
linelen -= len ;
return len ;
}
static int cnvhex( char *str )
{
static char *base = "0123456789ABCDEF" ;
int code = 0 ;
char *p ;
jstrupr( str ) ;
for( ; *str ; str++ )
{
code <<= 4 ;
if( ( p = strchr( base, *str ) ) == NULL )
return -1 ;
code += (int)(p - base) ;
}
return code ;
}
static void beep( void )
{
extern void write(int,char *,int);
write( 1, "\x07", 1 ) ;
}
static void chr_out( u_char ch )
{
if( CUR_X + 1 < SIZ_X )
{
if( ins_char( (char *)&linebuf[CUR_X] ) != -1 )
{
linebuf[CUR_X ++] = ch ;
/* DSP_BUF[ */ DSP_LEN++ /* ] = ch */ ;
typecheck( ktype, linebuf, linelen ) ;
return ;
}
}
beep() ;
}
static void key_del( void )
{
int len ;
if( linelen <= CUR_X )
return ;
len = del_char( CUR_X ) ;
linebuf[linelen] = ' ' ;
if( len == 2 )
linebuf[linelen+1] = ' ', linebuf[linelen+2] = '\0' ;
else
linebuf[linelen+1] = '\0' ;
CUR_POS = CUR_X ;
DSP_LEN = 1 ;
cflush() ;
linebuf[linelen] = '\0' ;
typecheck( ktype, linebuf, linelen ) ;
}
static void key_left( void )
{
if( CUR_X > 0 )
{
CUR_X-- ;
if( CUR_X > 0 &&
( ktype[CUR_X]==IS_KANJI2 || linebuf[CUR_X-1]==CTRL_PRE ) )
CUR_X-- ;
}
}
static void _inpch( int ch )
{
u_char *p;
char code_buf[3];
short code;
int i;
if (OPEN == FALSE) /* window がオープンしてなければパス */
return;
switch (ch)
{
case 0x0162: /* PF6 [範囲指定開始] */
if (CUT_X < 0)
cut_paste(TRUE);
else
cut_paste(FALSE);
break;
case 0x0163: /* PF7 [カット] */
if (CUT_POS != -1)
if (CUT_POS < CUR_POS) /* 指定されている */
{
strncpy(cutbuf, &linebuf[CUT_POS], CUR_POS-CUT_POS);
cutbuf[CUR_POS-CUT_POS] = '\0';
cut_paste(FALSE);
CUR_X = CUT_POS;
for (i = 0; i < jstrlen(cutbuf); i++)
key_del();
}
else
cut_paste(FALSE);
break;
case 0x0164: /* PF8 [コピー] */
if (CUT_POS != -1)
{
if (CUT_POS < CUR_POS) /* 指定されている */
{
strncpy(cutbuf, &linebuf[CUT_POS], CUR_POS-CUT_POS);
cutbuf[CUR_POS-CUT_POS] = '\0';
}
cut_paste(FALSE);
}
break;
case 0x0165: /* PF9 [ペースト] */
if (CUT_POS != -1)
{
cut_paste(FALSE);
}
else if(strlen(cutbuf) > 0)
{
for (p = (u_char *)cutbuf; *p != '\0'; p++)
inpch(*p);
}
break;
case 0x014E: /* HOME [先頭・末尾へ移動] */
if (CUR_X > 0)
CUR_X = 0;
else
CUR_X = linelen;
cflush();
break;
case 0x000B: /* CTRL-K [行末まで削除] */
while (CUR_X < linelen)
key_del();
break;
case 0x0016: /* CTRL-V [制御文字入力] */
pbox(264,MODE_Y-2, 264+112,MODE_Y+16+1, CHR_COL,CHR_COL);
wrt("制御文字入力", 272,MODE_Y, BAK_COL,CHR_COL, 16);
code_buf[2] = '\0' ;
code = -1;
if (isxdigit(code_buf[0] = getch())) {
if (isxdigit(code_buf[1] = getch()))
code = cnvhex(code_buf);
} else if (code_buf[0] < 0x20)
code = code_buf[0];
if (code != -1)
{
if (code < 0x20) /* 制御文字 */
chr_out(CTRL_PRE), chr_out(code|0x40);
else if (!iskanji(code)) /* 一般文字 */
chr_out(code);
else
beep();
}
int color = (writepage == 0) ? 15 : 0;
pbox(264,MODE_Y-2, 272+112,MODE_Y+16+1, color,color);
break;
case 0x314F: /* CTRL+シフト+左カーソル */
case 0x114F: /* シフト+左カーソル */
CUR_X = 0;
case 0x014F: /* 左カーソル */
case 0x0013: /* CTRL-S */
key_left();
cflush();
break;
case 0x3151: /* CTRL+シフト+右カーソル */
case 0x1151: /* シフト+右カーソル */
CUR_X = linelen;
case 0x0151: /* 右カーソル */
case 0x0004: /* CTRL-D */
if (CUR_X < linelen)
{
if (ktype[CUR_X] == IS_KANJI1 || linebuf[CUR_X] == CTRL_PRE)
CUR_X++;
CUR_X++;
}
cflush();
break;
case 0x010F: /* BS */
case 0x0008: /* CTRL-H */
if (CUR_X > 0)
{
key_left();
key_del();
}
break;
case 0x0015: /* CTRL_U [行頭まで削除] */
case 0x0018: /* CTRL-X */
while (CUR_X > 0)
{
key_left();
key_del();
}
break;
case 0x014B: /* DEL */
case 0x0007: /* CTRL-G */
key_del();
break;
default:
if ((ch & 0x0100) != 0) /* その他の制御キー */
break;
if (KAN_COD != 0)
{
if (iskanji2(ch))
{
if (CUR_X == (SIZ_X - 1))
chr_out(' ');
chr_out(KAN_COD);
chr_out(ch);
KAN_COD = 0;
return;
}
KAN_COD = 0;
}
if (iskanji(ch))
{
KAN_COD = ch;
return;
}
if (ch >= ' ')
{
chr_out(ch);
return;
}
}
}
void inpch(int ch)
{
MOS_disp(MOS_OFF);
_inpch(ch);
cflush();
MOS_disp(MOS_ON);
}
/*
void cputs(char *str)
{
while (*str != '\0')
inpch((unsigned char)*(str++));
}
void cprintf(char *form,...)
{
static char tmpbuf[256];
va_list arg;
va_start(arg, form);
vsprintf(tmpbuf, form, arg);
cputs(tmpbuf);
va_end(arg);
}
*/
/*
0 透過色 or 黒 8 テキスト背景色
1 黒 9 テキスト改行色
2 テキスト文字色(XOR時) 10 テキスト文字色
3 明るい黒 11 --
4 暗い緑 12 --
5 暗いシアン 13 暗い赤
6 暗い黄色 14 暗いマゼンダ
7 暗い白 15 明るい白 */
static u_short fortbl[] =
{
BAK_COL,BAK_COL,BAK_COL,BAK_COL,BAK_COL,BAK_COL,BAK_COL,BAK_COL,
BAK_COL,BAK_COL,BAK_COL,BAK_COL,BAK_COL,BAK_COL,BAK_COL,BAK_COL,
} ;
static u_short baktbl[] =
{
CHR_COL,CHR_COL,4,14,14,5,CHR_COL, CHR_COL,
CHR_COL,CHR_COL,CHR_COL,CHR_COL,CHR_COL,CHR_COL,CHR_COL,CHR_COL,
} ;
/* 0 読み
1 読み残し
2 未確定文字列
3 仮確定文字列
4 変換対象文節
5 現変換対象文節
6 カ-ソル位置
*/
static void KAN_putstr( int pos, int len, char *str, char *att )
{
static int bak_len = 0 ;
static char *bak_buf[128] = { NULL } ;
static char para[16] ;
auto int i, x, y, n, m ;
auto char *p ;
auto int TOPx = TOP_X ;
if( OPEN == FALSE )
return ;
if( ( TOPx % 2 ) == 1 )
TOPx -- ;
MOS_disp( MOS_OFF ) ;
for( i = 0 ; i < bak_len ; i++ ) /* 文字列消去 */
{
EGB_putBlock( gwork, 0, bak_buf[i] ) ;
free( bak_buf[i] ) ;
}
/* cflush() ; */ /* これをやると飛びます */
bak_len = 0 ;
x = CUR_X ; y = 0 ;
if( ( m = len ) > 0 && len == pos )
m ++ ;
for( i = 0 ; i < m ; i += n ) /* 文字列表示 */
{
n = ( i < len && iskanji( *str ) ) ? 2 : 1 ;
if( ( ( x + n ) * 8 + TOPx ) > 638 )
{
x = 0 ;
y ++ ;
}
if( ( p = (char *)malloc(FNT_X * FNT_Y * n * PIX_BYTE + 14)) == NULL )
break ;
DWORD(p+0) = (unsigned int)(p+14) ;
WORD(p+4) = 0x014 ; /* Data Selecter */
WORD(p+6) = TOPx + x * FNT_X ;
WORD(p+8) = TOP_Y + y * FNT_Y ;
WORD(p+10) = WORD(p+6) + n * FNT_X - 1 ;
WORD(p+12) = WORD(p+8) + FNT_Y - 1 ;
EGB_getBlock( gwork, p ) ;
bak_buf[bak_len++] = p ;
if( i < len )
{
para[0] = *str ;
if( n == 2 )
para[1] = *(str+1), para[2] = '\0' ;
else
para[1] = '\0' ;
wrt( para, WORD(p+6),WORD(p+8),
fortbl[*att],baktbl[*att], FSIZE ) ;
str += n ;
att += n ;
}
if( i == pos )
{
EGB_writeMode( gwork, MODE_XOR ) ;
pbox( WORD(p+6),WORD(p+8)+14, WORD(p+6)+7,WORD(p+8)+15, 2,2 ) ;
EGB_writeMode( gwork, MODE_PSET ) ;
}
x += n ;
if( ( x * 8 + TOPx ) >= 638 )
{
x = 0 ;
y ++ ;
}
}
MOS_disp( MOS_ON ) ;
}
static void KAN_putsys(int len, char *str, char *att)
{
const X_POS = 16, Y_POS = 460;
static int bak_len = 0;
static char *bak_buf = NULL;
char tmpbuf[4];
int i, x, n;
if (OPEN == FALSE)
return;
MOS_disp(MOS_OFF);
if (bak_len > 0)
{
DSP_putBlock(X_POS,Y_POS, bak_len * FNT_X - 1,FNT_Y - 1, bak_buf);
free(bak_buf);
}
bak_len = 0;
if (len == 0)
{
MOS_disp(MOS_ON);
return;
}
bak_buf = malloc(FNT_X * FNT_Y * (((len + 8) / 8) * 8) * PIX_BYTE);
if (bak_buf == NULL)
{
MOS_disp(MOS_ON);
return;
}
DSP_getBlock(X_POS,Y_POS, len * FNT_X - 1,FNT_Y - 1, bak_buf);
bak_len = len;
for (x = X_POS, i = 0; i < len; i += n)
{
n = iskanji(*str) ? 2 : 1;
tmpbuf[0] = *str;
if (n == 2)
tmpbuf[1] = *(str+1), tmpbuf[2] = '\0';
else
tmpbuf[1] = '\0';
wrt(tmpbuf, x,Y_POS, fortbl[*att], baktbl[*att], FSIZE);
str += n;
att += n;
x += (FNT_X * n);
}
MOS_disp(MOS_ON);
}
static void KAN_putmode(int mode, int shift_status, char *str)
{
mode = mode, shift_status = shift_status; /* Warnings 回避 */
strcpy(kan_mode, str);
if (OPEN == FALSE)
return;
MOS_disp(MOS_OFF);
KAN_dispMode();
MOS_disp(MOS_ON);
}
static int using_kkc = FALSE;
void KAN_start(void)
{
KYB_init();
KYB_clic(1); /* clic off */
KAN_open(KAN_putstr, KAN_putsys, KAN_putmode);
KAN_setposMode(MODE_X, MODE_Y);
using_kkc = TRUE;
}
void KAN_end(void)
{
using_kkc = FALSE;
KAN_close();
}
static int mode_x_pos, mode_y_pos;
void KAN_setposMode(int x, int y) /* モード表示位置を指定 */
{
mode_x_pos = x;
mode_y_pos = y;
}
void KAN_dispMode(void) /* モードを再表示 */
{
if (using_kkc != TRUE)
return;
pbox(mode_x_pos-4,mode_y_pos-2, mode_x_pos+71,mode_y_pos+16+1,
BLACK,BAK_COL);
wrt(kan_mode, mode_x_pos,mode_y_pos, CHR_COL,BAK_COL, FSIZE);
}